/**
 * @Project : algorithm-learning
 * @Author : Ruoyu Wang
 * @User : Momenta
 * @DateTime : 2024/3/16 16:51
 */

//小美拿到了一个排列，她定义f(i)为：将第i个元素取反后，形成的数组的逆序对数量。小美希望你求出f(1)到f(n)的值。
//排列是指一个长度为n的数组，1到n每个元素恰好出现了一次。
//
//输入描述
//  第一行输入一个正整数n，代表排列的大小。
//  第二行输入n个正整数a_i，代表排列的元素。
//  1<= n <=200000
//  1<= ai <=n
//
//输出描述
//  输出n个整数，第i个整数是f(i)的值。
//
//示例 1
//输入
//3
//1 2 3
//输出
//0 1 2
//说明
//  第一个元素取反，数组将变成[-1,2,3]，逆序对数量为 0。
//  第二个元素取反，数组将变成[1,-2,3]，逆序对数量为 1。
//  第三个元素取反，数组将变成[1,2,-3]，逆序对数量为 2。

#include <iostream>

using namespace std;
const int N = 2 * 1e5 + 10;
int sum = 0;

void mergeSort(int a[], int l, int r) {
    if (l >= r) return;
    int mid = (l + r) / 2;
    mergeSort(a, l, mid);
    mergeSort(a, mid + 1, r);

    int tmp[r - l + 1];
    int lp = l;
    int rp = mid + 1;
    int tmpp = 0;
    while (lp <= mid && rp <= r) {
        if (a[lp] <= a[rp]) {
            tmp[tmpp++] = a[lp++];
        } else {
            tmp[tmpp++] = a[rp++];
            sum += (mid - lp + 1);
        }
    }
    while (lp <= mid) {
        tmp[tmpp++] = a[lp++];
    }
    while (rp <= r) {
        tmp[tmpp++] = a[rp++];
    }
    for (int i = l, j = 0; i <= r; ++i, ++j) {
        a[i] = tmp[j];
    }
}

int main() {
    int n;
    scanf("%d", &n);
    int a[n], pre[n], post[n];
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < n; ++i) {
        post[i] = 0;
        pre[i] = 0;
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (j < i && a[j] < a[i]) pre[i]++;
            if (i < j && a[i] > a[j]) post[i]++;
        }
    }


    mergeSort(a, 0, n - 1);

    for (int i = 0; i < n; ++i) {
        printf("%d ", sum + pre[i] - post[i]);
    }

    return 0;
}